<?php

namespace Muyuxuanpay\pay;

use Muyuxuanpay\pay\common\Tool;
use Muyuxuanpay\tool\Mtool;

abstract class BasePay
{
    use Tool;
    protected $errorMessage = [];
    //pay_type的返回类型1=官方数据包支付,2=跳转H5支付,3=跳转微信小程序支付,4=跳转支付宝小程序支付,5=使用token跳转到小程序支付
    //$paymentType wxapp/wxmini/wxh5/wxwap/alipaymini/alipayapp/alipayh5/alipaywap
    protected $paymentType = [
        'wxapp',
        'wxmini',
        'wxh5',
        'wxwap',
        'alipaymini',
        'alipayapp',
        'alipayh5',
        'alipaywap',
    ];
    public function __construct(array $config = [], ?string $mode = null)
    {
        if(empty($config)){
            if(!empty($mode)){
                $fileName = __DIR__.'./config/'.$mode.'.php';
                if(is_file($fileName)){
                    $newconfig = require $fileName;
                    $config = array_merge($newconfig,$config);
                }
                $this->config = $config;
            }else{
                throw new \Exception('请设置支付配置');
            }
        }else {
            if (!empty($mode)) {
                $fileName = __DIR__ . '/config/' . $mode . '.php';
                if (is_file($fileName)) {
                    $newconfig = require $fileName;
                    $this->config = Mtool::depth_array_merge($newconfig, $config);
                }else{
                    $this->config = $config;
                }
            }else{
                $this->config = $config;
            }
        }

    }

    /**
     * @param $totalPrice
     * @param $paymentType
     * @param $orderNo
     * @param $noticeUrl
     * @param $backUrl
     * @param $goodsDesc
     * @param $payTimeOut
     * @param array $event
     * @return mixed 'pay_type'=>5,'resource'=>$content  pay_type=5是收银台支付resource[appId,path],pay_type=1时是官方数据包支付(微信和支付包不相同)，pay_type=2时是H5支付resource[url]，pay_type=3时是html跳转支付resource[form]，pay_type=4时是url跳转支付[url]
     * @throws \Exception
     */
    public function pay($totalPrice,$paymentType,$orderNo,$noticeUrl="",$backUrl="",$goodsDesc='',$payTimeOut='',array $event=[]){
        if(!in_array($paymentType,$this->paymentType)){
            throw new \Exception('支付类型错误');
        }
        if(!method_exists($this,$paymentType)){
            throw new \Exception('支付类型错误');
        }
        return $this->$paymentType($totalPrice,$orderNo,$noticeUrl,$backUrl,$goodsDesc,$payTimeOut,$event);
    }

    /**
     * 查询订单
     * @param $orderNo
     * @return void  [status:1=交易成功,2=已撤销,4=待支付状态,5=已关闭,6=部分退款,7=全部退款,8=转入退款,9=用户支付中,10=支付失败,11=交易失败,12=交易未知]
     * message=消息，order_no=订单号，resource=返回的其他信息
     */
    abstract function QueryOrderNo(?string $orderNo);

    /**
     * 订单退款
     * @param string|null $orderNo 订单号
     * @param string|null $refundNo 退款号
     * @param string|null $allPrice 订单金额
     * @param string|null $refundPrice 退款金额
     * @param string $noticeUrl 回调地址
     * @param string|null $refundReason 退款原因
     * @param array $event 其他参数
     *[status:1=交易成功,8=转入退款,11=交易失败]
     * @return false
     */
    abstract function RefundOrderNo(string $orderNo,string $refundNo,$allPrice,$refundPrice,$noticeUrl='',string $refundReason='',array $event=[]);

    /**
     * 绑定用户
     * @param array|null $data
     * @param string|null $orderNo
     * @return mixed
     * @throws \Exception
     */
    public function BinUser(?array $data,?string $orderNo=null){
        throw new \Exception('请实现该方法');
    }

    /**
     * 解绑用户
     * @param string|null $orderNo
     * @return mixed
     * @throws \Exception
     */
    public function UnbinUser(?array $data,?string $orderNo){
        throw new \Exception('请实现该方法');
    }

    /**
     * 查询绑定用户
     * @param array|null $data
     * @param string|null $orderNo
     * @return mixed
     * @throws \Exception
     */
    public function QueryBinUser(?array $data,?string $orderNo){
        throw new \Exception('请实现该方法');
    }

    public function getErrorMessage(){
        return $this->errorMessage;
    }
}